package com.surfilter.geet.code;
import com.surfilter.geet.RamdomUtil;
import com.surfilter.geet.StringParseUtils;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.openqa.selenium.*;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriverService;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.awt.*;
import java.io.File;
import java.util.*;
import java.util.List;
//
public class PhantomJSDriverGeetest {
    private static Robot robot = null;
    private static int px = MouseInfo.getPointerInfo().getLocation().x;
    private static int py = MouseInfo.getPointerInfo().getLocation().y;
    private static Logger logger = LoggerFactory.getLogger(PhantomJSDriverGeetest.class);

    static{
        try {
            robot = new Robot();
        } catch (AWTException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public static void main(String[] args) throws InterruptedException, Exception {
        DesiredCapabilities dcp = new DesiredCapabilities();
        dcp.setJavascriptEnabled(true);
        dcp.setPlatform(Platform.WINDOWS);
        dcp.setBrowserName("Chrome");
        dcp.setCapability("phantomjs.page.settings.userAgent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.109 Safari/537.36");
        dcp.setCapability("phantomjs.page.settings.loadImages", true);
        dcp.setCapability("phantomjs.page.settings.resourceTimeout", 3000);
        dcp.setCapability(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY, "E:\\software\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe");
        PhantomJSDriver driver = new PhantomJSDriver(dcp);
        driver.manage().window().setSize(new Dimension(1440, 900));
        driver.get("http://www.gsxt.gov.cn/index.html");
        Thread.sleep(3000);
        driver.findElementByCssSelector("input[name='searchword']").sendKeys("华为技术");
        Thread.sleep(5000);
        driver.findElementByCssSelector("#btn_query").click();
        Thread.sleep(8000);
        int num = 0;
        boolean target = false;
        while(true){
            target = validateGeetest(driver);
            num ++;
            System.out.println("第" + num + "次验证:" + target);
            if(target)break;
            Thread.sleep(3000);
        }

        WebElement userNameInput = driver.findElement(By.cssSelector("#loginForm > div > div.login-inputs > div:nth-child(1) > input"));
        WebElement passwordInput = driver.findElement(By.cssSelector("#loginForm > div > div.login-inputs > div:nth-child(3) > input"));
        WebElement enterButton = driver.findElement(By.cssSelector("#btnLogin"));

        userNameInput.sendKeys("18510726819");
        passwordInput.sendKeys("qwer1234");
        enterButton.click();
        Thread.sleep(3000);


        WebElement msglink = driver.findElement(By.cssSelector("#qxb-navbar > ul.nav.navbar-nav.navbar-right > li:nth-child(1) > a"));

        System.out.println(msglink.getText());

        Set<Cookie> cookies = driver.manage().getCookies();

        Map<String,String> cs = new HashMap<String,String>();

        for(Cookie c : cookies){
            System.out.println(c.getName() + "=" + c.getValue());
            cs.put(c.getName(), c.getValue());
        }

        Connection con = Jsoup.connect("http://www.qixin.com/search?key=%E4%BB%BB%E5%AD%90%E8%A1%8C%E7%BD%91%E7%BB%9C%E6%8A%80%E6%9C%AF%E8%82%A1%E4%BB%BD%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8&type=enterprise&method=");
        con.validateTLSCertificates(false);

        con.timeout(30000);
        con.header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
        con.header("Accept-Encoding", "gzip, deflate, sdch");
        con.header("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4");
        con.header("Cache-Control", "no-cache");
        con.header("Connection", "keep-alive");
        con.header("Pragma", "no-cache");
        con.header("Upgrade-Insecure-Requests", "1");
        con.header("User-Agent",
                "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36");
        con.cookies(cs);

        Document doc = con.get();

        Elements alink = doc.select("#container-onlineSearch > div:nth-child(11) > div.search-list-bg > div:nth-child(1) > div.search-ent-left > div.search-ent-left-content > a");
        Element el = alink.get(0);
        System.out.println(el.text());

        driver.close();
        driver.quit();
    }


    public static boolean validateGeetest(PhantomJSDriver driver) throws InterruptedException{
        RemoteWebElement remoteEle = null;
        boolean target = false;
        List<WebElement> divs = driver.findElementsByXPath("//div[@class='gt_slider_knob gt_show']");
        if(divs == null || divs.isEmpty())return target;
        WebElement ele = divs.get(0);
        if(ele instanceof RemoteWebElement){
            remoteEle = (RemoteWebElement)ele;
        }else return target;
        System.out.println("Ele.X:" + remoteEle.getLocation().x + "	Ele.Y:" + remoteEle.getLocation().y);
        List<WebElement> images = driver.findElementsByXPath("//div[@class='gt_cut_fullbg gt_show']/div[@class='gt_cut_fullbg_slice'][1]");
        if(images == null || images.isEmpty())return target;
        WebElement imageEle = images.get(0);
        String regex = "http://.*\\.jpg";
        String url1 = imageEle.getAttribute("style");
        url1 = StringParseUtils.parseString(url1, regex, false);


        List<WebElement> imagebgs = driver.findElementsByXPath("//div[@class='gt_cut_bg gt_show']/div[@class='gt_cut_bg_slice'][1]");
        if(imagebgs == null || imagebgs.isEmpty())return target;
        WebElement imagebgEle = imagebgs.get(0);
        String url2 = imagebgEle.getAttribute("style");
        url2 = StringParseUtils.parseString(url2, regex, false);

        int length = 0;
        try {
            length = GeetestImage.getMoveLength(url1, url2 , UUID.randomUUID().toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(length == 0)return target;
        System.out.println(length);
//		pageHelper.mouseDownEleMove(ele, length - 29, 500);
////		pageHelper.moveMouseToPoint(destPoint);
        driver.getMouse().mouseMove(remoteEle.getCoordinates());
        saveImage(driver, "C:/opt/rzx/geente/before.jpg");
        driver.getMouse().mouseDown(remoteEle.getCoordinates());
        Thread.sleep(RamdomUtil.getRandomNum(50, 100));
        saveImage(driver, "C:/opt/rzx/geente/down.jpg");
//        moveRemoteWebElementWindows(driver, length - 29);
        moveRemoteWebElementWindowsTest(driver, length - 29);
        Thread.sleep(RamdomUtil.getRandomNum(50, 200));
        System.out.println("Ele.X:" + remoteEle.getLocation().x + "	Ele.Y:" + remoteEle.getLocation().y);
        saveImage(driver, "C:/opt/rzx/geente/move.jpg");
        driver.getMouse().mouseUp(remoteEle.getCoordinates());
        Thread.sleep(RamdomUtil.getRandomNum(500, 800));
        saveImage(driver, "C:/opt/rzx/geente/result.jpg");
        List<WebElement> success = driver.findElementsByXPath("//div[@class='gt_ajax_tip gt_success']");
        if(success == null || success.isEmpty())target = false;
        else target = true;
        return target;
    }

    public static void moveRemoteWebElementLinux(PhantomJSDriver driver, int length){
        int px = MouseInfo.getPointerInfo().getLocation().x;
        int py = MouseInfo.getPointerInfo().getLocation().y;
        long start = System.currentTimeMillis();
        long end = start;
        try{
            int sum = 0;
            int max = 15;
            int min = 5;
            int sleep_max = 500;
            int sleep_min = 100;
            while(true){
                int subLength = RamdomUtil.getRandomNum(min, max);
                int x = 0;
                int y = RamdomUtil.getRandomNum(-3, 3);
                if(sum + subLength > length){
                    x = length - sum;
                }else{
                    x = subLength;
                }
                driver.getMouse().mouseMove(null, x, y);
                px += x;
                py += y;
                robot.mouseMove(px, py);
                sum += subLength;
                if(sum >= length)break;
                Thread.sleep(RamdomUtil.getRandomNum(sleep_min, sleep_max));
                if(length - sum < 50){
                    max = 4;
                    min = -1;
                    sleep_min = 10;
                    sleep_max = 40;
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        end = System.currentTimeMillis();
        System.out.println("移动鼠标耗时:" + (end - start));
    }
//windows环境下
    public static void moveRemoteWebElementWindows(PhantomJSDriver driver, int length){
//        int px = MouseInfo.getPointerInfo().getLocation().x;
//        int py = MouseInfo.getPointerInfo().getLocation().y;
        long start = System.currentTimeMillis();
        long end = start;
        try{
            int sum = 0;
            int max = 10;
            int min = 5;
            int sleep_max = 300;
            int sleep_min = 50;
            while(true){
                int subLength = RamdomUtil.getRandomNum(min, max);
                int x = 0;
                int y = RamdomUtil.getRandomNum(-3, 2);
                if(sum + subLength > length){
                    x = length - sum;
                }else{
                    x = subLength;
                }
                driver.getMouse().mouseMove(null, x, y);
//                px += x;
//                py += y;
//                robot.mouseMove(px, py);
                sum += subLength;
//                long now = System.currentTimeMillis();
//                System.out.println("["+sum+","+y+","+(now-start)+"]");
                if(sum >= length)break;
                Thread.sleep(RamdomUtil.getRandomNum(sleep_min, sleep_max));
                if(length - sum < 15){
                    max = 4;
                    min = -2;
                    sleep_min = 50;
                    sleep_max = 100;
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        end = System.currentTimeMillis();
        System.out.println("移动鼠标耗时:" + (end - start));
    }


    public static void moveRemoteWebElementWindowsTest(PhantomJSDriver driver, int length){
        long start = System.currentTimeMillis();
        long end = start;
        try{
            int sum = 0;
            int max;
            int min;
            int sleep_max;
            int sleep_min;
            int subLength;
            int sleepTime;
            while(true){
                //滑动总长度一旦超过滑块之间的距离，直接跳出循环
                if(sum >= length)break;
                if(sum < 2){
                    //用户接触滑块时的肌肉时延
                    subLength = 1;
                    sleep_min = 150;
                    sleep_max = 300;
                    sleepTime = RamdomUtil.getRandomNum(sleep_min, sleep_max);
                    sum = moveShortDistance(driver, subLength, sum, sleepTime);
                }
                if(sum < 5 && sum >= 2){
                    //起始
                    max = 2;
                    min = 1;
                    subLength = RamdomUtil.getRandomNum(min, max);
                    sleep_min = 20;
                    sleep_max = 50;
                    sleepTime = RamdomUtil.getRandomNum(sleep_min, sleep_max);
                    sum = moveShortDistance(driver, subLength, sum, sleepTime);
                }
                if(sum >= 5 && length - sum > 15){
                    //中间拖动
                    sleep_min = 10;
                    sleep_max = 15;
                    int i= 1;
                    subLength = getDistance(i);
                    i++;
                    // TODO: 2017/6/13 分析轨迹中间部分运行的函数轨迹
                    sleepTime = RamdomUtil.getRandomNum(sleep_min, sleep_max);
                    sum = moveShortDistance(driver, subLength, sum, sleepTime);
                }
                if(length - sum <= 15){
                    //结尾
                    min = -2;
                    max = 4;
                    subLength = RamdomUtil.getRandomNum(1,2);
                    int j =1;
                    sleepTime = getSleepTime(j);
                    j++;
                    sum = moveShortDistance(driver, subLength, sum, sleepTime);
                }
                // TODO: 2017/6/13 超过距离的处理
//                if(sum + subLength > length){
//                    x = length - sum;
//                }else{
//                    x = subLength;
//                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        end = System.currentTimeMillis();
        System.out.println("移动鼠标耗时:" + (end - start));
    }

    private static int getSleepTime(int j) {
        int sleep_min = -20;
        int sleep_max = 400;
        double y = 15.775*j - 17.267;
        int sleepTime = (int) y +RamdomUtil.getRandomNum(sleep_min, sleep_max);
        if(sleepTime < 0){
            return -sleepTime;
        }else{
            return sleepTime;
        }
    }

    private static int getDistance(int i) {
        double y = -0.0891*i + 6.2891;
        return (int) y +RamdomUtil.getRandomNum(-4, 4);
    }

    public static int moveShortDistance(PhantomJSDriver driver, int subLength, int sum, int sleepTime){
        int x = subLength;
//        int y = RamdomUtil.getRandomNum(-1, 1);
        int y = 0;
        driver.getMouse().mouseMove(null, x, y);
        //
        px += x;
        py += y;
        robot.mouseMove(px, py);
        logger.info("[" + x + "," + y + "," + y + "," + sleepTime +"]");
        //
        sum += subLength;
        try {
            Thread.sleep(sleepTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return sum;
    }

    public static void saveImage(PhantomJSDriver driver, String filePath){
        File destFile = new File(filePath);
        if(destFile.exists())destFile.delete();
        File sourceFile = driver.getScreenshotAs(OutputType.FILE);
        sourceFile.renameTo(new File(filePath));
    }


}
